/*
 * Reformer.com Inc.
 * Copyright (c) 20017-2022 All Rights Reserved.
 */
package com.reformer.commons.utils;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

public class ThreadSafeDateUtil {

    /**
     * 锁对象
     */
    private static final Object lock = new Object();
    /**
     * 存放不同的日期模板格式的sdf的Map
     */
    private static Map<String, ThreadLocal<SimpleDateFormat>> sdfMap = new HashMap<String, ThreadLocal<SimpleDateFormat>>();

    private ThreadSafeDateUtil() {
    }

    /**
     * 返回一个ThreadLocal的sdf,每个线程只会new一次sdf
     *
     * @param pattern
     * @return
     */
    private static SimpleDateFormat getSdf(final String pattern) {
        ThreadLocal<SimpleDateFormat> sdf = sdfMap.get(pattern);
        // 此处的双重判断和同步是为了防止sdfMap这个单例被多次put重复的sdf
        if (sdf == null) {
            synchronized (lock) {
                sdf = sdfMap.get(pattern);
                if (sdf == null) {
                    // 只有Map中还没有这个pattern的sdf才会生成新的sdf并放入map
                    // 这里是关键,使用ThreadLocal<SimpleDateFormat>替代原来直接new
                    // SimpleDateFormat
                    sdf = new ThreadLocal<SimpleDateFormat>() {
                        @Override
                        protected SimpleDateFormat initialValue() {
                            return new SimpleDateFormat(pattern);
                        }
                    };
                    sdfMap.put(pattern, sdf);
                }
            }
        }
        return sdf.get();
    }

    /**
     * 格式化日期
     *
     * @param date    日期
     * @param pattern 模式
     * @return
     */
    public static String format(Date date, String pattern) {
        return getSdf(pattern).format(date);
    }

    /**
     * 格式：yyyy-MM-dd HH:mm:ss
     *
     * @param date 日期
     * @return
     */
    public static String formatByDefaultPattern(Date date) {
        return getSdf("yyyy-MM-dd HH:mm:ss").format(date);
    }

    /**
     * 格式：yyyyMMddHHmmss
     *
     * @param date 日期
     * @return
     */
    public static String formatByConcisePattern(Date date) {
        return getSdf("yyyyMMddHHmmss").format(date);
    }

    /**
     * 日期解析
     *
     * @param dateStr
     * @param pattern
     * @return
     * @throws ParseException
     */
    public static Date parse(String dateStr, String pattern) throws ParseException {
        return getSdf(pattern).parse(dateStr);
    }

    /**
     * 格式：yyyy-MM-dd HH:mm:ss
     *
     * @param dateStr
     * @return
     * @throws ParseException
     */
    public static Date parseByDefaultPattern(String dateStr) throws ParseException {
        return getSdf("yyyy-MM-dd HH:mm:ss").parse(dateStr);
    }

    /**
     * 格式：yyyyMMddHHmmss
     *
     * @param dateStr
     * @return
     * @throws ParseException
     */
    public static Date parseByConcisePattern(String dateStr) throws ParseException {
        return getSdf("yyyyMMddHHmmss").parse(dateStr);
    }

    public static Date parse(String dateStr) throws ParseException {
        return getSdf("yyyyMMddHHmmss").parse(dateStr.replaceAll("\\D+", ""));
    }
}
